using System;
using System.Collections.Generic;
using System.Text;

namespace Toenda.Foundation {
	public static class Arithmetic {
		/// <summary>
		/// Round a negative number to null
		/// </summary>
		/// <param name="num"></param>
		/// <returns></returns>
		public static double GetNonNegative(double num) {
			return ((num + Math.Abs(num)) / 2);
		}

		/// <summary>
		/// Calculates the product of a list of values
		/// </summary>
		/// <param name="valueList"></param>
		/// <returns></returns>
		public static double Product(List<double> valueList) {
			double sum = 0;
			bool isFirst = true;

			foreach(double value in valueList) {
				if(isFirst) {
					sum += value;
				}
				else {
					sum *= value;
				}

				isFirst = false;
			}

			return sum;
		}

		/// <summary>
		/// Get the average sum of all values in a list
		/// </summary>
		/// <param name="valueList"></param>
		/// <returns></returns>
		public static double Average(List<double> valueList) {
			double sum = 0;

			foreach(double value in valueList) {
				sum += value;
			}

			return (sum / valueList.Count);
		}

		/// <summary>
		/// Convert a double to a decimal with a 100 percent accuracy, but on a dirty and slow way.
		/// </summary>
		/// <param name="value"></param>
		/// <param name="digits"></param>
		/// <returns></returns>
		public static decimal DirtyConvertToDecimal(double value, int digits) {
			string tmp = value.ToString();

			string p1 = tmp.Substring(0, tmp.IndexOf(","));
			string p2 = tmp.Substring(tmp.IndexOf(",") + 1);

			string dec = p1 + ",";

			if(p2.Length >= digits) {
				dec += p2.Substring(0, digits);
			}
			else {
				dec += p2.Substring(0, p2.Length);
			}

			return Convert.ToDecimal(dec);
		}

		/// <summary>
		/// Round and reduce
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		public static double ReduceRound(double value) {
			value = Math.Floor(value * 100);
			value /= 100;
			return value;
		}

		/// <summary>
		/// Round and reduce
		/// </summary>
		/// <param name="value"></param>
		/// <param name="decimals"></param>
		/// <returns></returns>
		public static double ReduceRound(double value, int decimals) {
			int dec = (int)Math.Pow(10.0, (double)decimals);
			value = Math.Floor(value * dec);
			value /= dec;
			return value;
		}
	}
}
